package net.documentshare.documentconfig;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import net.documentshare.common.CommonUtils;
import net.documentshare.common.ECommonType;
import net.documentshare.docu.DocuBean;
import net.documentshare.docu.DocuUtils;
import net.documentshare.docu.EDocuStatus;
import net.documentshare.ftp.FtpConfig;
import net.documentshare.ftp.FtpSession;
import net.documentshare.utils.ItSiteUtil;
import net.simpleframework.organization.OrgUtils;
import net.simpleframework.util.ConvertUtils;
import net.simpleframework.web.WebUtils;

import org.dom4j.Element;
import org.json.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;

/**
 * ftp存储
 *
 */
public class FtpStorageBean extends StorageBean {
	public FtpStorageBean(Element ele) {
		super(ele);
	}

	public String url;
	public String host;
	public int port;
	public String user, pass;

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
		ele.addAttribute("host", host);
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		ele.addAttribute("port", String.valueOf(port));
		this.port = port;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		ele.addAttribute("user", user);
		this.user = user;
	}

	public String getPass() {
		return pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
		ele.addAttribute("pass", pass);
	}

	@Override
	public String getType() {
		return "ftp";
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
		ele.addAttribute("url", url);
	}

	@Override
	protected void initStorage(Element ele) {
		super.initStorage(ele);
		this.host = ele.attributeValue("host");
		this.port = ConvertUtils.toInt(ele.attributeValue("port"), 21);
		this.user = ele.attributeValue("user");
		this.pass = ele.attributeValue("pass");
		this.url = ele.attributeValue("url");
		this.path = ele.attributeValue("path");
	}

	@Override
	public boolean hasFreeSpace() {
		try {
			Connection conn = Jsoup.connect(WebUtils.addParameters(url, "cmd=freeSpace&diskSpace=" + diskSpace + "&path=" + this.path));
			if (conn != null) {
				conn.timeout(1000 * 60 * 60);
				final JSONObject jsonMap = new JSONObject(conn.get().body().text());
				if ("true".equals(jsonMap.get("act"))) {
					if (jsonMap.has("space"))
						return ConvertUtils.toBoolean(jsonMap.get("space"), false);
				}
			}
		} catch (Exception e) {
		}
		return false;
	}

	private FtpSession createFtpSession(final String path, final String name) {
		return new FtpSession(new FtpConfig(host, port, user, pass, path, name));
	}

	@Override
	public boolean canDelete() {
		final FtpSession session = createFtpSession("", "");
		try {
			return session.listDirectory().size() == 0 && session.listFilesPath().size() == 0;
		} catch (IOException e) {
			return false;
		}
	}

	@Override
	public void deleteFile(String filePath, String fileName) {
		try {
			Connection conn = Jsoup.connect(WebUtils.addParameters(url, "cmd=delete&path=" + toLocalString(path + filePath + fileName)));
			if (conn != null) {
				conn.timeout(1000 * 60 * 60);
				conn.get();
			}
		} catch (Exception e) {
		}
	}

	@Override
	public void uploadFile(InputStream is, String filePath, String fileName) {
		try {
			final String path = this.path + filePath;
			if (createDirectory(path)) {
				final FtpSession session = createFtpSession(filePath, fileName);
				if (session.testConnnected())
					session.putFile(is, new String(toLocalString(fileName)));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean isFileExists(String filePath, final String fileName) {
		final FtpSession session = createFtpSession("", "");
		InputStream is = null;
		try {
			is = session.openInStream(toLocalString(filePath + fileName));
		} catch (IOException e) {
			return false;
		}
		return is != null;
	}

	@Override
	public boolean isDirectoryExists() {
		final FtpSession session = createFtpSession("", "");
		return session.testConnnected();
	}

	@Override
	public InputStream getInputStream(String path) {
		final FtpSession session = createFtpSession("", "");
		try {
			return session.openInStream(toLocalString(path));
		} catch (IOException e) {
		}
		return null;
	}

	@Override
	public int getPageCounter(String filePath) {
		try {
			final String path = this.path + filePath;
			Connection conn = Jsoup.connect(WebUtils.addParameters(url, "cmd=pages&path=" + path));
			if (conn != null) {
				conn.timeout(1000 * 60 * 60);
				final JSONObject jsonMap = new JSONObject(conn.get().body().text());
				if ("true".equals(jsonMap.get("act"))) {
					if (jsonMap.has("pages"))
						return ConvertUtils.toInt(jsonMap.get("pages"), 0);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	private String toLocalString(final String str) {
		try {
			return new String(str.getBytes("GBK"), "iso-8859-1");
		} catch (Exception e) {
		}
		return str;
	}

	@Override
	public Map<String, Boolean> listFiles(String filePath) {
		final Map<String, Boolean> fileMap = new LinkedHashMap<String, Boolean>();
		try {
			final FtpSession session = createFtpSession(filePath, "");
			final Collection<String> filePaths = session.listFilesPath();
			for (final String file : filePaths) {
				fileMap.put(WebUtils.toLocaleString(new File(file).getName()), false);
			}
			final Collection<String> fileDirectoryPaths = session.listDirectory();
			for (final String file : fileDirectoryPaths) {
				fileMap.put(file, true);
			}
		} catch (Exception e) {
		}
		return fileMap;
	}

	@Override
	public InputStream getInputStream(DocuBean docuBean, final String path) {
		try {
			final FtpSession session = createFtpSession("", "");
			return session.openInStream(DocuUtils.getDatabase(docuBean.getUserId()) + docuBean.getId() + "/" + path);
		} catch (IOException e) {
		}
		return null;
	}

	private boolean createDirectory(final String path) {
		Connection conn = Jsoup.connect(WebUtils.addParameters(url, "cmd=create&path=" + path));
		if (conn != null) {
			try {
				final JSONObject jsonMap = new JSONObject(conn.get().body().text());
				if ("true".equals(jsonMap.get("act"))) {
					return true;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	@Override
	public void convertDocument(DocuBean docuBean) {
		try {
			final String path = this.path + DocuUtils.getDatabase(docuBean.getUserId());
			Connection conn = Jsoup.connect(WebUtils.addParameters(url, "cmd=convert&path=" + path + "&id=" + docuBean.getId() + "&convertPages="
					+ CommonUtils.getContent(ECommonType.converNumber) + "&pages=" + docuBean.getAllowRead() + "&fileName=" + docuBean.getFileName()
					+ "&docuFunction=" + docuBean.getDocuFunction().name()));
			if (conn != null) {
				conn.timeout(1000 * 60 * 60);
				final JSONObject jsonMap = new JSONObject(conn.get().body().text());
				if ("true".equals(jsonMap.get("act"))) {
					// 如果是管理员或者开启自动审核，自动发布
					final boolean autoAudit = "true".equals(CommonUtils.getContent(ECommonType.docu_auto));
					if (jsonMap.has("success"))
						docuBean.setSuccess(ConvertUtils.toInt(jsonMap.get("success"), 3));
					if ((autoAudit || OrgUtils.isManagerMember(ItSiteUtil.getUserById(docuBean.getUserId()))) && docuBean.getSuccess() == 2) {
						docuBean.setStatus(EDocuStatus.publish);
					}
					if (jsonMap.has("pages"))
						docuBean.setFileNum(ConvertUtils.toInt(jsonMap.get("pages"), 0));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public String toString() {
		final StringBuffer buf = new StringBuffer();
		buf.append("服务：").append(url).append("<br/>");
		buf.append("路径：").append(path).append("<br/>");
		buf.append("主机：").append(host).append("<br/>");
		buf.append("端口：").append(port).append("<br/>");
		buf.append("用户：").append(user).append("<br/>");
		buf.append("密码：").append(pass).append("<br/>");
		return buf.toString();
	}

	@Override
	public String getFileNames(String filePath) {
		return "";
	}
}
